<?php
/**
 * Validation Class
 * v3.0
 * Last Updated: Mar 28, 2011
 * URL: http://www.nickyeoman.com/blog/php/104-php-validation-class
 *
 * Changelog:
 * v2 now works with PHP 5.3 and up
 * v3 is easy to intergrate into CI as a library (renamed) + bug fixes
 **/

class Validate {

	/**
	 * Checks if there are 7 or 10 numbers, if so returns cleaned parameter(no formating just numbers)
	 * other wise it will return false
	 * $phone is the phone number
	 * $ext if set to true return an array with extension separated
	 **/
	function isPhone($phone, $ext = false) {

		//remove everything but numbers
		$numbers = preg_replace("%[^0-9]%", "", $phone );

		//how many numbers are supplied
		$length = strlen($numbers);

		if ( $length == 10 || $length == 7 ) { //Everything is find and dandy

			$cleanPhone = $numbers;

			if ( $ext ) {
				$clean['phone'] = $cleanPhone;
				return $clean;
			} else {
				return $cleanPhone;
			}

		} elseif ( $length > 10 ) { //must be extension

			//checks if first number is 1 (this may be a bug for you)
			if ( substr($numbers,0,1 ) == 1 ) {
				$clean['phone'] = substr($numbers,0,11);
				$clean['extension'] = substr($numbers,11);
			} else {
				$clean['phone'] = substr($numbers,0,10);
				$clean['extension'] = substr($numbers,10);
			}

			if (!$ext) { //return string

				if (!empty($clean['extension'])) {
					$clean = implode("x",$clean);
				} else {
					$clean = $clean['phone'];
				}

				return $clean;


			} else { //return array

				return $clean;
			}
		}

		return false;

	}

	/**
	 * Canadian Postal code
	 * thanks to: http://roshanbh.com.np/2008/03/canda-postal-code-validation-php.html
	 **/
	function isPostalCode($postal) {
		$regex = "/^([a-ceghj-npr-tv-z]){1}[0-9]{1}[a-ceghj-npr-tv-z]{1}[0-9]{1}[a-ceghj-npr-tv-z]{1}[0-9]{1}$/i";

		//remove spaces
		$postal = str_replace(' ', '', $postal);

		if ( preg_match( $regex , $postal ) ) {
			return $postal;
		} else {
			return false;
		}

	}

	/**
	 * Checks for a 5 digit zip code
	 * Clears extra characters
	 * returns clean zip
	 **/
	function isZipCode($zip) {
		//remove everything but numbers
		$numbers = preg_replace("[^0-9]", "", $zip );

		//how many numbers are supplied
		$length = strlen($numbers);

		if ($length != 5) {
			return false;
		} else {
			return $numbers;
		}
	}

	/**
	 * Checks the length of a value
	 *
	 * @param string  $value The value to check
	 * @param integer $maxLength The maximum allowable length of the value
	 * @param integer $minLength [Optional] The minimum allowable length
	 * @return boolean TRUE if the requirements are met, FALSE if not
	 */
	function checkLength($value, $maxLength, $minLength = 0)
	{
		if (!(strlen($value) > $maxLength) && !(strlen($value) < $minLength)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Compares two values for equality
	 *
	 * @param string  $value1 First value to compare
	 * @param string  $value2 Second value to compare
	 * @param boolean $caseSensitive [Optional] TRUE if compare is case sensitive
	 * @return boolean TRUE if the values are equal and FALSE if not
	 */
	function compare($value1, $value2, $caseSensitive = false)
	{
		if ($caseSensitive) {
			return ($value1 ==  $value2 ? true : false);
		} else {
			if (strtoupper($value1) ==  strtoupper($value2)) {
				return true;
			} else {
				return false;
			}
		}
	}

	/**
	 * Converts any value of any datatype into boolean (true or false)
	 *
	 * @param any $value Value to analyze for TRUE or FALSE
	 * @param any $includeTrueValue (Optional) return TRUE if the value equals this
	 * @param any $includeFalseValue (Optional) return FALSE if the value equals this
	 * @return boolean Returns TRUE or FALSE
	 */
	function getBooleanValue($value, $includeTrueValue = null, $includeFalseValue = null) {

		if (!(is_null($includeTrueValue)) && $value == $includeTrueValue) {
			return true;
		} elseif (!(is_null($includeFalseValue)) && $value == $includeFalseValue) {
			return false;
		} else {
			if (gettype($value) == "boolean") {
				if ($value == true) {
					return true;
				} else {
					return false;
				}
			} elseif (is_numeric($value)) {
				if ($value > 0) {
					return true;
				} else {
					return false;
				}
			} else {
				$cleaned = strtoupper(trim($value));

				if ($cleaned == "ON") {
					return true;
				} elseif ($cleaned == "SELECTED" || $cleaned == "CHECKED") {
					return true;
				} elseif ($cleaned == "YES" || $cleaned == "Y") {
					return true;
				} elseif ($cleaned == "TRUE" || $cleaned == "T") {
					return true;
				} else {
					return false;
				}
			}
		}
	}

	/**
	 * Get the value for a cookie by the cookie name
	 *
	 * @param string  $name The name of the cookie
	 * @param string  $default (Optional) A default if the value is empty
	 * @return string The cookie value
	 */
	function getCookieValue($name, $default = '')
	{
		if (isset($_COOKIE[$name]))
		{
			return $_COOKIE[$name];
		} else {
			return $default;
		}
	}

	/**
	 * Returns the name of the current page
	 *
	 * @return string The page name
	 */
	function getCurrentPageName($lowercase = false) {
		$return = substr($_SERVER["SCRIPT_NAME"],
		strrpos($_SERVER["SCRIPT_NAME"], "/") + 1);
		return ($lowercase ? strtolower($return) : $return);
	}

	/**
	 * Returns the name of the current URL
	 *
	 * @return string The URL path
	 */
	function getCurrentPageURL($lowercase = false) {
		$pageURL = 'http';
		if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
		$pageURL .= "://";
		if ($_SERVER["SERVER_PORT"] != "80") {
			$pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
		} else {
			$pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
		}
		return ($lowercase ? strtolower($pageURL) : $pageURL);
	}

	/**
	 * Returns the value if one exists, otherwise returns a default value
	 * (This also works on NULL values)
	 *
	 * @param string  $name The value to check
	 * @param string  $default A default if the value is empty
	 * @return string Returns the original value unless this value is
	 *                empty - in which the default is returned
	 */
	function getDefaultOnEmpty($value, $default) {
		if (self::hasValue($value)) {
			return $value;
		} else {
			return $default;
		}
	}

	/**
	 * Get a POST or GET value by a form element name
	 *
	 * @param string  $name The name of the POST or GET data
	 * @param string  $default (Optional) A default if the value is empty
	 * @return string The value of the form element
	 */
	function getFormValue($name, $default = '')
	{
		if (isset($_POST[$name]))
		{
			return $_POST[$name];
		} else {
			if (isset($_GET[$name]))
			{
				return $_GET[$name];
			} else {
				return $default;
			}
		}
	}

	/**
	 * Get the value for a request
	 *
	 * @param string  $name The name of the request item
	 * @param string  $default (Optional) A default if the value is empty
	 * @return string The request value
	 */
	function getRequestValue($name, $default = '')
	{
		if (isset($_REQUEST[$name]))
		{
			return $_REQUEST[$name];
		} else {
			return $default;
		}
	}

	/**
	 * Get the value for a session by the session name
	 *
	 * @param string  $name The name of the session
	 * @param string  $default (Optional) A default if the value is empty
	 * @return string The session value
	 */
	function getSessionValue($name, $default = '')
	{
		if (isset($_SESSION[$name]))
		{
			return $_SESSION[$name];
		} else {
			return $default;
		}
	}

	/**
	 * Get a POST, GET, Session, or Cookie value by name
	 * (in that order - if one doesn't exist, the next is tried)
	 *
	 * @param string  $name The name of the POST, GET, Session, or Cookie
	 * @param string  $default (Optional) A default if the value is empty
	 * @return string The value from that element
	 */
	function getValue($name, $default = '')
	{
		if (isset($_POST[$name]))
		{
			return $_POST[$name];
		} else {
			if (isset($_GET[$name]))
			{
				return $_GET[$name];
			} else {
				if (isset($_SESSION[$name]))
				{
					return $_SESSION[$name];
				} else {
					if (isset($_COOKIE[$name]))
					{
						return $_COOKIE[$name];
					} else {
						return $default;
					}
				}
			}
		}
	}

	/**
	 * Checks to see if a variable contains a value
	 *
	 * @param string  $value The value to check
	 * @return boolean TRUE if a value exists, FALSE if empty
	 */
	function hasValue($value)
	{
		if (strlen($value) < 1 || is_null($value) || empty($value)) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Determines if a string is alpha only
	 *
	 * @param string $value The value to check for alpha (letters) only
	 * @param string $allow Any additional allowable characters
	 * @return boolean
	 */
	function isAlpha($value, $allow = '')
	{
		if (preg_match('/^[a-zA-Z' . $allow . ']+$/', $value))
		{
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Determines if a string is alpha-numeric
	 *
	 * @param string $value The value to check
	 * @return boolean TRUE if there are letters and numbers, FALSE if other
	 */
	function isAlphaNumeric($value)
	{
		if (preg_match("/^[A-Za-z0-9 ]+$/", $value))
		{
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Determines if a string contains a valid date
	 *
	 * @param string $value The value to inspect
	 * @return boolean TRUE if the value is a date, FALSE if not
	 */
	function isDate($value)
	{
		$date = date('Y', strtotime($value));
		if ($date == "1969" || $date == '')
		{
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Checks for a valid email address
	 *
	 * @param string  $email The value to validate as an email address
	 * @return boolean TRUE if it is a valid email address, FALSE if not
	 */
	function isEmail($email)
	{
		$pattern = "#^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+#";

		if (preg_match($pattern, $email))
		{
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Checks to see if a variable contains no value (not even a zero)
	 *
	 * @param string  $value The value to check
	 * @return boolean TRUE if a value exists, FALSE if empty
	 */
	function isEmpty($value)
	{
		if (strlen($value) < 1 || is_null($value)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Checks for a valid internet URL
	 *
	 * @param string $value The value to check
	 * @return boolean TRUE if the value is a valid URL, FALSE if not
	 */
	function isInternetURL($value)
	{
		if (preg_match("/^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?$/i", $value))
		{
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Checks for a valid IP Address
	 *
	 * @param string $value The value to check
	 * @return boolean TRUE if the value is an IP address, FALSE if not
	 */
	function isIPAddress($value)
	{
		$pattern = "/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i";
		if (preg_match($pattern, $value))
		{
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Checks to see if a variable is a number
	 *
	 * @param integer $number The value to check
	 * @return boolean TRUE if the value is a number, FALSE if not
	 */
	function isNumber($number)
	{
		if (preg_match("/^\-?\+?[0-9e1-9]+$/", $number))
		{
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Checks for a two character state abbreviation
	 *
	 * @param string $value The value to inspect
	 * @return boolean TRUE if the value is a 2 letter state abbreviation
	 *                 FALSE if the value is anything else
	 */
	function isStateAbbreviation($value)
	{
		if (preg_match("/^[A-Z][A-Z]$/i", $value))
		{
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Check to see if a string length is too long
	 *
	 * @param string $value The string value to check
	 * @param integer $maximumLength The maximum allowed length
	 * @return boolean TRUE if the length is too long
	 *                 FALSE if the length is acceptable
	 */
	function isTooLong($value, $maximumLength) {
		if (self::checkLength($value, $maximumLength)) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Check to see if a string length is too short
	 *
	 * @param string $value The string value to check
	 * @param integer $maximumLength The minimum allowed length
	 * @return boolean TRUE if the length is too short
	 *                 FALSE if the length is acceptable
	 */
	function isTooShort($value, $minimumLength) {
		if (strlen($value) < $minimumLength) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Checks to see if a variable is an unsigned number
	 *
	 * @param integer $number The value to inspect
	 * @return boolean TRUE if the value is a number without a sign
	 *                 and FALSE if a sign exists
	 */
	function isUnsignedNumber($number)
	{
		if (preg_match("/^\+?[0-9]+$/", $number))
		{
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Kiểm tra lỗi xss
	 * @param string $val
	 * @return mixed
	 */
	function xss($val) 
    {
        //axe all non printables
        $val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
        
        $search = 'abcdefghijklmnopqrstuvwxyz';
        $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $search .= '1234567890!@#$%^&*()';
        $search .= '~`";:?+/={}[]-_|\'\\';
        for($i = 0; $i < strlen($search); $i++) 
        {
            //axe all non characters
            $val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val);
            $val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val);
        }
       
        $ra1 = array(
            'javascript','vbscript','expression',
            'applet','meta','xml','blink','link',
            'style','script','embed','object',
            'iframe','frame','frameset','ilayer',
            'layer','bgsound','title','base');
        $ra2 = array(
            'onabort','onactivate','onafterprint',
            'onafterupdate','onbeforeactivate',
            'onbeforecopy','onbeforecut',
            'onbeforedeactivate','onbeforeeditfocus',
            'onbeforepaste','onbeforeprint',
            'onbeforeunload','onbeforeupdate','onblur',
            'onbounce','oncellchange','onchange','onclick',
            'oncontextmenu','oncontrolselect','oncopy',
            'oncut','ondataavailable','ondatasetchanged',
            'ondatasetcomplete','ondblclick','ondeactivate',
            'ondrag','ondragend','ondragenter',
            'ondragleave','ondragover','ondragstart',
            'ondrop','onerror','onerrorupdate',
            'onfilterchange','onfinish','onfocus',
            'onfocusin','onfocusout','onhelp','onkeydown',
            'onkeypress','onkeyup','onlayoutcomplete',
            'onload','onlosecapture','onmousedown',
            'onmouseenter','onmouseleave','onmousemove',
            'onmouseout','onmouseover','onmouseup',
            'onmousewheel','onmove','onmoveend','onmovestart',
            'onpaste','onpropertychange','onreadystatechange',
            'onreset','onresize','onresizeend','onresizestart',
            'onrowenter','onrowexit','onrowsdelete',
            'onrowsinserted','onscroll','onselect',
            'onselectionchange','onselectstart','onstart',
            'onstop','onsubmit','onunload');
        $ra = array_merge($ra1, $ra2);
       
        $found = true;
        while($found == true)
        {
            $val_before = $val;
            for($i = 0; $i < sizeof($ra); $i++) 
            {
                $pattern = '/';
                for($j = 0; $j < strlen($ra[$i]); $j++) 
                {
                    if($j > 0) 
                    {
                        $pattern .= '((&#[xX]0{0,8}([9ab]);)||(&#0{0,8}([9|10|13]);))*';
                    }
                    $pattern .= $ra[$i][$j];
                }
                
                $pattern .= '/i';
                //break all on*
                $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2);
                $val = preg_replace($pattern, $replacement, $val);
                if($val_before == $val) $found = false;
            }
        }
       return $val;
    } 
 
}
/** End Validation **/